home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / internet / sweeper / samples / olecon~1 / controls / invisi~1 / invisi~2.cpp < prev    next >
Text File  |  1995-11-25  |  16KB  |  595 lines

  1. //=--------------------------------------------------------------------------=
  2. // InvisibleCtl.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright  1995  Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. //
  13. //
  14. #include "IPServer.H"
  15.  
  16. #include "Guids.H"
  17. #include "InvisibleCtl.H"
  18. #include "LocalObj.H"
  19. #include "Util.H"
  20. #include "Globals.H"
  21. #include "Resource.H"
  22.  
  23. // for ASSERT and FAIL
  24. //
  25. SZTHISFILE
  26.  
  27. // NOTE: passing the control pointer this way implies that there can only be one
  28. //       instance of this control in a process, and generally is a pretty bad
  29. //       way of doing things.  however, it's convenient, and serves our purposes
  30. //       for this sample.
  31. //
  32. static CInvisibleControl *s_pCtl;
  33.  
  34. //=--------------------------------------------------------------------------=
  35. // for persistence
  36. //
  37. #define STREAMHDR_MAGIC    0x12345678
  38.  
  39. typedef struct {
  40.  
  41.     DWORD dwMagic;
  42.     DWORD dwVersion;
  43.     DWORD cbSize;
  44.  
  45. } STREAMHDR;
  46.  
  47. WCHAR wszTimeOut [] = L"TimeOut";
  48.  
  49.  
  50.  
  51.  
  52. //=--------------------------------------------------------------------------=
  53. // all the events in this control
  54. //
  55. typedef enum {
  56.     InvisibleEvent_Time = 0
  57. } INVISIBLEVENTS;
  58.  
  59. EVENTINFO m_rgEvents [] = {
  60.     { DISPIDE_TIME, 0, NULL }
  61. };
  62.  
  63. //=--------------------------------------------------------------------------=
  64. // array describing all of our property pages.  these clsids are typically
  65. // in guids.h
  66. //
  67. // TODO: add any additional property page guids here ...
  68. //
  69. const GUID *rgInvisiblePropPages [] = {
  70.     &CLSID_InvisibleGeneralPage
  71. };
  72.  
  73. //=--------------------------------------------------------------------------=
  74. // Custum Verb information
  75. //
  76. // TODO: add any custom verbs here in an array, using the VERBINFO structure.
  77. //       then mark the controld def'n in InvisibleCtl.H with
  78. //       this verb array
  79. //
  80.  
  81.  
  82. //=--------------------------------------------------------------------------=
  83. // CInvisibleControl::Create
  84. //=--------------------------------------------------------------------------=
  85. // global static function that creates an instance of the control an returns
  86. // an IUnknown pointer for it.
  87. //
  88. // Parameters:
  89. //    IUnknown *        - [in] controlling unknown for aggregation
  90. //
  91. // Output:
  92. //    IUnknown *        - new object.
  93. //
  94. // Notes:
  95. //
  96. IUnknown *CInvisibleControl::Create
  97. (
  98.     IUnknown *pUnkOuter
  99. )
  100. {
  101.     // make sure we return the private unknown so that we support aggegation
  102.     // correctly!
  103.     //
  104.     CInvisibleControl *pNew = new CInvisibleControl(pUnkOuter);
  105.     return pNew->PrivateUnknown();
  106. }
  107.  
  108. //=--------------------------------------------------------------------------=
  109. // CInvisibleControl::CInvisibleControl
  110. //=--------------------------------------------------------------------------=
  111. // "Being born is like being kidnapped.  And then sold into slavery."
  112. //    - andy warhol (1928 - 87)
  113. //
  114. // Parameters:
  115. //    IUnknown *        - [in]
  116. //
  117. // Notes:
  118. //
  119. #pragma warning(disable:4355)  // using 'this' in constructor
  120. CInvisibleControl::CInvisibleControl
  121. (
  122.     IUnknown *pUnkOuter
  123. )
  124. : COleControl(pUnkOuter, OBJECT_TYPE_CTLINVISIBLE, (IDispatch *)this)
  125. {
  126.  
  127.     memset(&m_state, 0, sizeof(INVISIBLECTLSTATE));
  128.  
  129.     // set default time out ot 1 second.
  130.     //
  131.     m_state.lTimeOut = 1;
  132.     m_fTimer = FALSE;
  133.     m_hIcon = NULL;
  134. }
  135. #pragma warning(default:4355)  // using 'this' in constructor
  136.  
  137. //=--------------------------------------------------------------------------=
  138. // CInvisibleControl::~CInvisibleControl
  139. //=--------------------------------------------------------------------------=
  140. // "We all labour against our own cure, for death is the cure of all diseases"
  141. //    - Sir Thomas Browne (1605 - 82)
  142. //
  143. // Notes:
  144. //
  145. CInvisibleControl::~CInvisibleControl ()
  146. {
  147.     // TODO: clean up anything here.
  148.     if (m_fTimer)
  149.         KillTimer(NULL, 666);
  150.  
  151. }
  152.  
  153. //=--------------------------------------------------------------------------=
  154. // CInvisibleControl:RegisterClassData
  155. //=--------------------------------------------------------------------------=
  156. // register the window class information for your control here.
  157. // this information will automatically get cleaned up for you on DLL shutdown.
  158. //
  159. // Output:
  160. //    BOOL            - FALSE means fatal error.
  161. //
  162. // Notes:
  163. //
  164. BOOL CInvisibleControl::RegisterClassData
  165. (
  166.     void
  167. )
  168. {
  169.     FAIL("This doesn't get called for InvisibleAtRuntime controls!");
  170.     return FALSE;
  171. }
  172.  
  173. //=--------------------------------------------------------------------------=
  174. // CInvisibleControl::InternalQueryInterface
  175. //=--------------------------------------------------------------------------=
  176. // qi for things only we support.
  177. //
  178. // Parameters:
  179. // Parameters:
  180. //    REFIID        - [in]  interface they want
  181. //    void **       - [out] where they want to put the resulting object ptr.
  182. //
  183. // Output:
  184. //    HRESULT       - S_OK, E_NOINTERFACE
  185. //
  186. // Notes:
  187. //
  188. HRESULT CInvisibleControl::InternalQueryInterface
  189. (
  190.     REFIID  riid,
  191.     void  **ppvObjOut
  192. )
  193. {
  194.     IUnknown *pUnk;
  195.  
  196.     *ppvObjOut = NULL;
  197.  
  198.     // TODO: if you want to support any additional interrfaces, then you should
  199.     // indicate that here.  never forget to call COleControl's version in the
  200.     // case where you don't support the given interface.
  201.     //
  202.     if (DO_GUIDS_MATCH(riid, IID_IInvisible)) {
  203.         pUnk = (IUnknown *)(IInvisible *)this;
  204.     } else{
  205.         return COleControl::InternalQueryInterface(riid, ppvObjOut);
  206.     }
  207.  
  208.     pUnk->AddRef();
  209.     *ppvObjOut = (void *)pUnk;
  210.     return S_OK;
  211. }
  212.  
  213. //=--------------------------------------------------------------------------=
  214. // CInvisibleControl::LoadTextState
  215. //=--------------------------------------------------------------------------=
  216. // load in our text state for this control.
  217. //
  218. // Parameters:
  219. //    IPropertyBag *        - [in] property bag to read from
  220. //    IErrorLog *           - [in] errorlog object to use with proeprty bag
  221. //
  222. // Output:
  223. //    HRESULT
  224. //
  225. // Notes:
  226. //    - NOTE: if you have a binary object, then you should pass an unknown
  227. //      pointer to the property bag, and it will QI it for IPersistStream, and
  228. //      get said object to do a Load()
  229. //
  230. STDMETHODIMP CInvisibleControl::LoadTextState
  231. (
  232.     IPropertyBag *pPropertyBag,
  233.     IErrorLog    *pErrorLog
  234. )
  235. {
  236.     VARIANT v;
  237.     HRESULT hr;
  238.  
  239.     v.vt = VT_I4;
  240.     v.lVal = 0;
  241.  
  242.     // load in the TimeOut property.  nothing terribly serious. we ignore any
  243.     // failure so that if it can't be found, we just use the default of 1 sec.
  244.     //
  245.     hr = pPropertyBag->Read(wszTimeOut, &v, pErrorLog);
  246.     if (SUCCEEDED(hr)) m_state.lTimeOut = v.lVal;
  247.  
  248.     return S_OK;
  249. }
  250.  
  251. //=--------------------------------------------------------------------------=
  252. // CInvisibleControl::LoadBinaryState
  253. //=--------------------------------------------------------------------------=
  254. // loads in our binary state using streams.
  255. //
  256. // Parameters:
  257. //    IStream *            - [in] stream to write to.
  258. //
  259. // Output:
  260. //    HRESULT
  261. //
  262. // Notes:
  263. //
  264. STDMETHODIMP CInvisibleControl::LoadBinaryState
  265. (
  266.     IStream *pStream
  267. )
  268. {
  269.     STREAMHDR sh;
  270.     HRESULT   hr;
  271.  
  272.     // first read in the streamhdr, and make sure we like what we're getting
  273.     //
  274.     hr = pStream->Read(&sh, sizeof(sh), NULL);
  275.     RETURN_ON_FAILURE(hr);
  276.  
  277.     // sanity check
  278.     //
  279.     if (sh.dwMagic != STREAMHDR_MAGIC || sh.cbSize != sizeof(m_state))
  280.         return E_UNEXPECTED;
  281.  
  282.     // read in the control state information
  283.     //
  284.     hr = pStream->Read(&(m_state), sizeof(m_state), NULL);
  285.     RETURN_ON_FAILURE(hr);
  286.  
  287.     return S_OK;
  288. }
  289.  
  290. //=--------------------------------------------------------------------------=
  291. // CInvisibleControl::SaveTextState
  292. //=--------------------------------------------------------------------------=
  293. // saves out the text state for this control using a property bag.
  294. //
  295. // Parameters:
  296. //    IPropertyBag *        - [in] the property bag with which to work.
  297. //    BOOL                  - [in] if TRUE, then write out ALL properties, even
  298. //                            if they're their the default value ...
  299. //
  300. // Output:
  301. //    HRESULT
  302. //
  303. // Notes:
  304. //
  305. STDMETHODIMP CInvisibleControl::SaveTextState
  306. (
  307.     IPropertyBag *pPropertyBag,
  308.     BOOL          fWriteDefaults
  309. )
  310. {
  311.     HRESULT hr;
  312.     VARIANT v;
  313.  
  314.     v.vt = VT_I4;
  315.     v.lVal = m_state.lTimeOut;
  316.  
  317.     // save out the TimeOut property if it's not it's default value.
  318.     //
  319.     if ((m_state.lTimeOut != 1) || fWriteDefaults)
  320.         hr = pPropertyBag->Write(wszTimeOut, &v);
  321.  
  322.     return hr;
  323. }
  324.  
  325. //=--------------------------------------------------------------------------=
  326. // CInvisibleControl::SaveBinaryState
  327. //=--------------------------------------------------------------------------=
  328. // save out the binary state for this control, using the given IStream object.
  329. //
  330. // Parameters:
  331. //    IStream  *             - [in] save to which you should save.
  332. //
  333. // Output:
  334. //    HRESULT
  335. //
  336. // Notes:
  337. //    - it is important that you seek to the end of where you saved your
  338. //      properties when you're done with the IStream.
  339. //
  340. STDMETHODIMP CInvisibleControl::SaveBinaryState
  341. (
  342.     IStream *pStream
  343. )
  344. {
  345.     STREAMHDR sh = { STREAMHDR_MAGIC, MAKELONG(1, 0), sizeof(m_state) };
  346.     HRESULT hr;
  347.  
  348.     // write out the stream hdr.
  349.     //
  350.     hr = pStream->Write(&sh, sizeof(sh), NULL);
  351.     RETURN_ON_FAILURE(hr);
  352.  
  353.     // write out he control state information
  354.     //
  355.     hr = pStream->Write(&m_state, sizeof(m_state), NULL);
  356.     return hr;
  357. }
  358.  
  359. //=--------------------------------------------------------------------------=
  360. // CInvisibleControl::OnSetExtent
  361. //=--------------------------------------------------------------------------=
  362. // called whenever we're about to resize the puppy.
  363. //
  364. // Parameters:
  365. //    SIZEL *    - [in] new desired size.
  366. //
  367. // Output:
  368. //    BOOL       - FALSE means we want a different size than that passed in.
  369. //
  370. // Notes:
  371. //
  372. BOOL CInvisibleControl::OnSetExtent
  373. (
  374.     SIZEL *pSize
  375. )
  376. {
  377.     // set up our initial size ... + 6 so we can have raised edge
  378.     //
  379.     m_Size.cx = 6 + GetSystemMetrics(SM_CXICON);
  380.     m_Size.cy = 6 + GetSystemMetrics(SM_CYICON);
  381.  
  382.     return FALSE;
  383. }
  384.  
  385. //=--------------------------------------------------------------------------=
  386. // _TimerProc
  387. //=--------------------------------------------------------------------------=
  388. //
  389. void CALLBACK _TimerProc
  390. (
  391.     HWND hwnd,
  392.     UINT uMsg,
  393.     UINT idTimer,
  394.     DWORD dwTime
  395. )
  396. {
  397.     ASSERT(s_pCtl, "Maggots!");
  398.  
  399.     s_pCtl->FireEvent(&(m_rgEvents[InvisibleEvent_Time]));
  400. }
  401.  
  402. //=--------------------------------------------------------------------------=
  403. // CInvisibleControl::FreezeEvents    [IOleControl]
  404. //=--------------------------------------------------------------------------=
  405. // allows a container to freeze all of a controls events.  when events are
  406. // frozen, a control will not fire any of them.
  407. //
  408. // Parameters:
  409. //    BOOL            - [in] TRUE means FREEZE, FALSE means THAW
  410. //
  411. // Output:
  412. //    HRESULT         - S_OK
  413. //
  414. // Notes:
  415. //    - we maintain an internal count of freezes versus thaws.
  416. //
  417. STDMETHODIMP CInvisibleControl::FreezeEvents
  418. (
  419.     BOOL fFreeze
  420. )
  421. {
  422.     // if we're not in design mode, go and create the timer callback
  423.     // sucker!
  424.     //
  425.     if (m_fTimer) {
  426.         KillTimer(NULL, 666);
  427.         m_fTimer = FALSE;
  428.         s_pCtl = NULL;
  429.     }
  430.     if (m_state.lTimeOut) {
  431.         m_fTimer = TRUE;
  432.         SetTimer(NULL, 666, m_state.lTimeOut * 1000, (TIMERPROC)_TimerProc);
  433.         s_pCtl = this;
  434.     }
  435.  
  436.     return S_OK;
  437. }
  438.  
  439.  
  440. //=--------------------------------------------------------------------------=
  441. // CInvisibleControl::OnDraw
  442. //=--------------------------------------------------------------------------=
  443. // "I don't very much enjoy looking at paintings in general.  i know too
  444. //  much about them.  i take them apart."
  445. //    - georgia o'keeffe (1887-1986)
  446. //
  447. // Parameters:
  448. //    HDC                - [in]  HDC to draw to
  449. //    LPCRECTL           - [in]  rect we're drawing to
  450. //    LPCRECTL           - [in]  window extent and origin for meta-files
  451. //    HDC                - [in]  HIC for target device
  452. //
  453. // Output:
  454. //    HRESULT
  455. //
  456. // Notes:
  457. //
  458. HRESULT CInvisibleControl::OnDraw
  459. (
  460.     HDC      hdcDraw,
  461.     LPCRECTL prcBounds,
  462.     LPCRECTL prcWBounds,
  463.     HDC      hicTargetDevice
  464. )
  465. {
  466.     if (!m_hIcon)
  467.         m_hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_INVISIBLEICON));
  468.  
  469.     DrawEdge(hdcDraw, (LPRECT)(LPCRECT)prcBounds, EDGE_RAISED, BF_RECT | BF_MIDDLE);
  470.  
  471.     if (m_hIcon)
  472.         DrawIcon(hdcDraw, prcBounds->left + 3, prcBounds->top + 3, m_hIcon);
  473.  
  474.     return S_OK;
  475. }
  476.  
  477. //=--------------------------------------------------------------------------=
  478. // CInvisibleControl::WindowProc
  479. //=--------------------------------------------------------------------------=
  480. // window procedure for this control.  nothing terribly exciting.
  481. //
  482. // Parameters:
  483. //     see win32sdk on window procs.
  484. //
  485. // Notes:
  486. //
  487. LRESULT CInvisibleControl::WindowProc
  488. (
  489.     HWND   hwnd,
  490.     UINT   msg,
  491.     WPARAM wParam,
  492.     LPARAM lParam
  493. )
  494. {
  495.     // TODO: handle any messages here, like in a normal window
  496.     // proc.  note that for special keys, you'll want to override and
  497.     // implement OnSpecialKey.
  498.     //
  499.     return DefWindowProc(hwnd, msg, wParam, lParam);
  500. }
  501.  
  502. //=--------------------------------------------------------------------------=
  503. // CInvisibleControl::AboutBox
  504. //=--------------------------------------------------------------------------=
  505. // prints up an about box.  fweeeee.
  506. //
  507. // Notes:
  508. //
  509. void CInvisibleControl::AboutBox
  510. (
  511.     void
  512. )
  513. {
  514.     // TODO: Ideally, one would use DialogBox, and some sort of Dialog Box here if
  515.     // they wanted a slightly more interesting About Box ...  you should
  516.     // still call ModalDialog first, however.
  517.     //
  518.     ModalDialog(TRUE);
  519.     MessageBox(NULL, "This is My Control", "About Invisible", MB_OK | MB_TASKMODAL);
  520.     ModalDialog(FALSE);
  521. }
  522.  
  523. //=--------------------------------------------------------------------------=
  524. // CInvisibleControl::get_TimeOut    [IInvisible]
  525. //=--------------------------------------------------------------------------=
  526. // returns current time out value
  527. //
  528. // Parameters:
  529. //    long *        - [out] value is in seconds.
  530. //
  531. // Output:
  532. //    HRESULT
  533. //
  534. // Notes:
  535. //
  536. STDMETHODIMP CInvisibleControl::get_TimeOut
  537. (
  538.     long *plTimeOut
  539. )
  540. {
  541.     CHECK_POINTER(plTimeOut);
  542.     *plTimeOut = m_state.lTimeOut;
  543.     return S_OK;
  544. }
  545.  
  546. //=--------------------------------------------------------------------------=
  547. // CInvisibleControl::put_TimeOut    [IInvisible]
  548. //=--------------------------------------------------------------------------=
  549. // sets current timeout
  550. //
  551. // Parameters:
  552. //    long             - [in] value is in seconds.
  553. //
  554. // Output:
  555. //    HRESULT
  556. //
  557. // Notes:
  558. //
  559. STDMETHODIMP CInvisibleControl::put_TimeOut
  560. (
  561.     long lTimeOut
  562. )
  563. {
  564.     if (lTimeOut == m_state.lTimeOut)
  565.         return S_OK;
  566.  
  567.     m_state.lTimeOut = lTimeOut;
  568.  
  569.     // clean ou the old dude first!
  570.     //
  571.     if (m_fTimer) {
  572.         KillTimer(NULL, 666);
  573.         m_fTimer = FALSE;
  574.         s_pCtl = NULL;
  575.     }
  576.  
  577.     if (m_state.lTimeOut) {
  578.  
  579.         // create a new timer.
  580.         //
  581.         m_fTimer = TRUE;
  582.         SetTimer(NULL, 666, m_state.lTimeOut * 1000, (TIMERPROC)_TimerProc);
  583.         s_pCtl = this;
  584.     }
  585.     
  586.     // be-de-be-de-be-de-be-de that's all folks!
  587.     //
  588.     PropertyChanged(DISPID_TIMEOUT);
  589.     m_fDirty = TRUE;
  590.     return S_OK;
  591. }
  592.  
  593.  
  594.  
  595.